package com.thd.springboottest.security.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * com.thd.springboottest.security.utils.JwtTokenUtil
 *
 * @author: wanglei62
 * @DATE: 2022/6/22 15:05
 **/
public class JwtTokenUtil implements Serializable {
    private static final long serialVersionUID = -2550185165626007488L;
    // 单位是秒
    public static final long JWT_TOKEN_VALIDITY = 7*24*60*60;
//    public static final long JWT_TOKEN_VALIDITY = 60;

    private  String secret="TcUF7CC8T3txmfQ38pYsQ3KY";

    private static JwtTokenUtil instance = null;
    static {
        instance = new JwtTokenUtil();
    }

    public static JwtTokenUtil getInstance(){
        return instance;
    }

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    /**
     * 生成token
     * @param username
     * @return
     */
    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, username);
    }

    public String generateToken(String username,Map<String, Object> claims) {
        if(null==claims) {
           claims = new HashMap<>();
        }
        return doGenerateToken(claims, username);
    }

    /**
     * 验证Token是否合法
     * @param token
     * @param userDetails
     * @return
     */
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }


    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    /**
     * 获取claim信息
     * @param token
     * @return
     */
    public Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    /**
     * 判断token是否过期
     * @param token
     * @return
     */
    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    /**
     * 获取到期时间
     * @param token
     * @return
     */
    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    /**
     * 签发JWT
     * @param claims 主要的用户信息
     * @param subject 用户名/电话号码/邮箱 等用户标识
     * @return
     */
    private String doGenerateToken(Map<String, Object> claims, String subject) {
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY*1000)).signWith(SignatureAlgorithm.HS512, secret).compact();
    }

//    public static void main(String[] args){
//        Map<String,Object> user = new HashMap<String,Object>();
//        user.put("mobile","13800138000");
//        user.put("email","thd@qq.com");
//        user.put("username","thd");
//        JwtTokenUtil util = new JwtTokenUtil();
//        String jwtToken = util.doGenerateToken(user,user.get("username").toString());
//        System.out.println(jwtToken);
//
//        Claims claims = util.getAllClaimsFromToken(jwtToken);
//        System.out.println(claims);
//
//    }

}
